﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LockDemo
{
    public class MyTask
    {
        public List<int> MyList = new List<int>();


        public void DoSync()
        {
            //如果认为该方法永远不会有多个线程并发执行的情况，则不需要同步机制
            for (int i = 0; i < 1000; i++)
            {
                MyList.Add(i);
                Thread.Sleep(new Random().Next(10));
            }
            Console.WriteLine("List count:" + MyList.Count);
        }

        public void DoParallelWithoutLock()
        {
            for (int i = 0; i < 1000; i++)
            {
                MyList.Add(i);
                Thread.Sleep(new Random().Next(10));
            }

            Console.WriteLine("List count:" + MyList.Count);
        }


        public void DoParallelByLockString()
        {
            lock ("aa")
            {
                for (int i = 0; i < 1000; i++)
                {
                    MyList.Add(i);
                    Thread.Sleep(new Random().Next(10));
                }

                Console.WriteLine("List count:" + MyList.Count);
            }
        }

        public void DoParallelByLockThis()
        {
            lock (this)
            {
                for (int i = 0; i < 1000; i++)
                {
                    MyList.Add(i);
                    Thread.Sleep(new Random().Next(10));
                }
                Console.WriteLine("List count:" + MyList.Count);
            }
        }

        public void DoParallelByLockMethodLevelFiled()
        {
            object obj = new object();
            lock (obj)
            {
                for (int i = 0; i < 1000; i++)
                {
                    MyList.Add(i);
                    Thread.Sleep(new Random().Next(10));
                }
                Console.WriteLine("List count:" + MyList.Count);
            }
        }

        //如果不同的实例拥有同一个资源，为防止冲突，建议使用static
        private static readonly object objForAllInstance = new object();

        //如果不同实例拥有不同的资源
        private readonly object obj = new object();

        public void DoParallelByLockCorrectly()
        {
            lock (obj) // 或 objForAllInstance
            {
                for (int i = 0; i < 1000; i++)
                {
                    MyList.Add(i);
                    Thread.Sleep(new Random().Next(10));
                }
                Console.WriteLine("List count:" + MyList.Count);
            }
        }
    }
}
